﻿//
//                       _oo0oo_
//                      o8888888o
//                      88" . "88
//                      (| -_- |)
//                      0\  =  /0
//                    ___/`---'\___
//                  .' \\|     |// '.
//                 / \\|||  :  |||// \
//                / _||||| -:- |||||- \
//               |   | \\\  -  /// |   |
//               | \_|  ''\---/''  |_/ |
//               \  .-\__  '-'  ___/-. /
//             ___'. .'  /--.--\  `. .'___
//          ."" '<  `.___\_<|>_/___.' >' "".
//         | | :  `- \`.;`\ _ /`;.`/ - ` : | |
//         \  \ `_.   \_ __\ /__ _/   .-` /  /
//     =====`-.____`.___ \_____/___.-`___.-'=====
//                       `=---='
//
//
//     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
//               佛祖保佑         永无BUG
//
//     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

#region << 版 本 注 释 >>

/*----------------------------------------------------------------
* 类 名 称 ：GameObjectHelper
* 类 描 述 ：
* 作    者 ：henrychang
* 创建时间 ：2019/1/5 15:31:48
*******************************************************************
* Copyright @ henrychang 2018. All rights reserved.
*******************************************************************
//----------------------------------------------------------------*/

#endregion << 版 本 注 释 >>

using System;
using System.Linq;
using UnityEngine;

/// <summary>
/// 用于快速简单地查找和操作游戏对象
/// </summary>
public class GameObjectHelper
{
    /// <summary>
    /// 获取具有给定名称的第一个子游戏对象的组件
    /// </summary>
    /// <typeparam name="TComponent"></typeparam>
    /// <param name="thisGameObject"></param>
    /// <param name="name"></param>
    /// <param name="includeInactive"></param>
    /// <returns></returns>
    public static TComponent GetChildComponentOnNamedGameObject<TComponent>(GameObject thisGameObject, String name, bool includeInactive = false) where TComponent : Component
    {
        TComponent[] components = thisGameObject.GetComponentsInChildren<TComponent>(includeInactive);
        return components.FirstOrDefault(component => component.gameObject.name == name);
    }

    /// <summary>
    /// 获取具有给定名称的第一个子游戏对象
    /// </summary>
    /// <param name="thisGameObject"></param>
    /// <param name="name"></param>
    /// <param name="includeInactive"></param>
    /// <returns></returns>
    public static GameObject GetChildNamedGameObject(GameObject thisGameObject, string name, bool includeInactive = false)
    {
        Transform[] components = thisGameObject.GetComponentsInChildren<Transform>(includeInactive);
        return (from component in components where component.gameObject.name == name select component.gameObject).FirstOrDefault();
    }

    /// <summary>
    /// 获取具有给定名称的第一个父级游戏对象
    /// </summary>
    /// <param name="thisGameObject"></param>
    /// <param name="name"></param>
    /// <returns></returns>
    public static GameObject GetParentNamedGameObject(GameObject thisGameObject, string name)
    {
        while (true)
        {
            if (thisGameObject.name == name) return thisGameObject;
            if (thisGameObject.transform.parent == null) return null;
            thisGameObject = thisGameObject.transform.parent.gameObject;
        }
    }

    /// <summary>
    /// 通过禁用物理和放置在视图之外禁用要删除的游戏对象。
    /// </summary>
    /// <param name="gameObject"></param>
    public static void DisableGameObjectForRemoval(GameObject gameObject)
    {
        if (gameObject.GetComponent<Collider2D>() != null)
            gameObject.GetComponent<Collider2D>().enabled = false;
        if (gameObject.GetComponent<Rigidbody2D>() != null)
            gameObject.GetComponent<Rigidbody2D>().isKinematic = true;
        gameObject.transform.position = new Vector3(0, -20); // place out of view
    }

    /// <summary>
    /// 递归地将gameobjects设置为指定的层名称
    /// </summary>
    /// <param name="gameObject"></param>
    /// <param name="layerName"></param>
    public static void SetLayerRecursive(GameObject gameObject, string layerName)
    {
        SetLayerRecursive(gameObject, LayerMask.NameToLayer(layerName));
    }

    /// <summary>
    /// 递归地将游戏对象设置到指定的层
    /// </summary>
    /// <param name="gameObject"></param>
    /// <param name="layer"></param>
    public static void SetLayerRecursive(GameObject gameObject, int layer)
    {
        gameObject.layer = layer;
        for (int i = 0; i < gameObject.transform.childCount; i++)
        {
            SetLayerRecursive(gameObject.transform.GetChild(i).gameObject, layer);
        }
    }

    /// <summary>
    /// 销毁所有子游戏对象
    /// </summary>
    /// <param name="root"></param>
    public static void DestroyChildren(Transform root)
    {
        int childCount = root.childCount;
        for (int i = 0; i < childCount; i++)
        {
            UnityEngine.Object.Destroy(root.GetChild(i).gameObject);
        }
    }

    /// <summary>
    /// 首先安全地设置游戏对象活动状态测试，以确定是否已被销毁
    /// </summary>
    /// <param name="gameObject"></param>
    /// <param name="value"></param>
    /// <returns></returns>
    public static bool SafeSetActive(GameObject gameObject, bool value)
    {
        if (gameObject != null)
        {
            gameObject.SetActive(value);
            return true;
        }
        return false;
    }
}